package com.zqwh.yj.sdk.model;

import android.os.Handler;

import com.rfid.uhf.reader16.ReadTag;
import com.rfid.uhf.reader16.TagCallback;
import com.zqwh.yj.sdk.obj.AntConfig;
import com.zqwh.yj.sdk.utils.CommonUtils;
import com.zqwh.yj.sdk.utils.CountDownTimerUtil;
import com.zqwh.yj.sdk.utils.LogUtils;
import com.zqwh.yj.sdk.utils.StringUtils;


import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;


/**
 * Created by eason.yang on 2018/7/8.
 */

public class RfidRr16ModelImpl implements RfidModel {
    private final static int INV_STATE_IDLE = 0;
    private final static int INV_STATE_ING = 1;
    private final static int INV_STATE_WAIT = 2;
    private final static int INV_STATE_INIT = 3;

    private CountDownTimerUtil mTimeCounter;
    private int mTickCount = 0;

    private InventoryListener mInventoryTagListener;
    private Map<String, Integer> mTagsMap = new LinkedHashMap<>();
    private int mInvState = INV_STATE_IDLE;
    private String mUartPath;
    private int mBaudRate;
    private int mAntNumber = 8;
    private int mRfPower;

    public RfidRr16ModelImpl(int antNumber, String uartPath, int baudRate, int rfPower) {
        this.mAntNumber = antNumber;
        this.mUartPath = uartPath;
        this.mBaudRate = baudRate;
        this.mRfPower = rfPower;
    }

    @Override
    public int setAntConfigs(List<AntConfig> antConfigs) {
        return 0;
    }

    @Override
    public int connectSerialPort() {
        mInvState = INV_STATE_INIT;
        switch (mAntNumber){
            case 16:
                UHFReader16.param.setAnts(new int[]{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16});
                break;
            case 15:
                UHFReader16.param.setAnts(new int[]{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 17});
                break;
            case 14:
                UHFReader16.param.setAnts(new int[]{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 17, 18});
                break;
            case 13:
                UHFReader16.param.setAnts(new int[]{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 17, 18, 19});
                break;
            case 12:
                UHFReader16.param.setAnts(new int[]{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 17, 18, 19, 20});
                break;
            case 11:
                UHFReader16.param.setAnts(new int[]{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 17, 18, 19, 20, 21});
                break;
            case 10:
                UHFReader16.param.setAnts(new int[]{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 17, 18, 19, 20, 21, 22});
                break;
            case 9:
                UHFReader16.param.setAnts(new int[]{1, 2, 3, 4, 5, 6, 7, 8, 9, 17, 18, 19, 20, 21, 22, 23});
                break;
            case 8:
                UHFReader16.param.setAnts(new int[]{1, 2, 3, 4, 5, 6, 7, 8, 17, 18, 19, 20, 21, 22, 23, 24});
                break;
            case 7:
                UHFReader16.param.setAnts(new int[]{1, 2, 3, 4, 5, 6, 7, 17, 18, 19, 20, 21, 22, 23, 24, 25});
                break;
            case 6:
                UHFReader16.param.setAnts(new int[]{1, 2, 3, 4, 5, 6, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26});
                break;
            case 5:
                UHFReader16.param.setAnts(new int[]{1, 2, 3, 4, 5, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27});
                break;
            case 4:
                UHFReader16.param.setAnts(new int[]{1, 2, 3, 4, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28});
                break;
            case 3:
                UHFReader16.param.setAnts(new int[]{1, 2, 3, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29});
                break;
            case 2:
                UHFReader16.param.setAnts(new int[]{1, 2, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30});
                break;
            case 1:
                UHFReader16.param.setAnts(new int[]{1, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31});
                break;
        }

        UHFReader16.reader.setReaderParam(UHFReader16.param);
        LogUtils.logout("Uart path : "+mUartPath);
        LogUtils.logout("Baud rate : "+mBaudRate);
        int ret = UHFReader16.reader.openReader(mUartPath, mBaudRate);
        if (0 == ret) {
            UHFReader16.reader.SetRfPower(mRfPower);
            UHFReader16.reader.initReader();
        }else {
            LogUtils.error("Fail to set rfid module : "+ret);
        }

        mInvState = INV_STATE_IDLE;
        return 0;
    }

    @Override
    public int startInventoryTag(int inventoryTime, final InventoryListener listener) {
        if (mInvState != INV_STATE_IDLE) {
            LogUtils.logout("Start inventory, retry...");
            return -1;
        }
        LogUtils.logout("Inventory time : "+inventoryTime+"ms");
        mInventoryTagListener = listener;
        UHFReader16.reader.setTagsCallback(new TagCallback() {
            @Override
            public void tagCallback(ReadTag[] readTags) {
                if (mInvState == INV_STATE_ING) {
                    for (ReadTag readTag : readTags) {
                        Integer findIndex = mTagsMap.get(readTag.epcId);
                        if (findIndex == null) {
                            mTagsMap.put(readTag.epcId, mTagsMap.size());
                        }
                    }
                }
            }

            @Override
            public int tagCallbackFailed(int i) {
                return 0;
            }

            @Override
            public void updateBackResult(int i) {

            }
        });
        mTimeCounter = new CountDownTimerUtil(inventoryTime, 1000) {
            @Override
            public void onTick(long millisUntilFinished) {
                if (mTickCount != 0){
                    mInventoryTagListener.onInventoryTick(mTickCount, mTagsMap.size());
                }
                mTickCount = mTickCount + 1;
            }
            @Override
            public void onFinish() {
                stopInventoryTag();
                mInventoryTagListener.onInventoryTick(mTickCount, mTagsMap.size());
                List<String> tagListTmp = CommonUtils.tagsToEpcs(mTagsMap);
                mInventoryTagListener.onInventoryTagFinish(tagListTmp);
                mTickCount = 0;
            }
        };
        mInvState = INV_STATE_ING;
        mTagsMap.clear();
        mTimeCounter.start();
        return UHFReader16.reader.startRead();
    }

    @Override
    public int startInventoryTag(int antId, int power, InventoryListener listener) {
        return 0;
    }

    @Override
    public int startInventoryTag(int startAntId, int endAntId, int inventoryTime, InventoryListener listener) {
        return 0;
    }

    @Override
    public int stopInventoryTag() {
        mInvState = INV_STATE_WAIT;
        new Handler().postDelayed(new Runnable(){
            public void run() {
                mInvState = INV_STATE_IDLE;
            }
        }, 20 * 1000);
        mTimeCounter.cancel();
        return UHFReader16.reader.stopRead();
    }

    @Override
    public void finishInventoryTag() {
        mTimeCounter.onFinish();
    }

    @Override
    public String getAllAntSWR() {
        String swrAll = "";
        for (int i = 0; i < mAntNumber; i++){
            int[] swr = new int[1];
            UHFReader16.reader.getAntSWR(i, swr);
            int antNum = i + 1;
            if (StringUtils.isEmpty(swrAll)){
                swrAll = antNum+"-"+swr[0];
            }else {
                swrAll = swrAll+", "+antNum+"-"+swr[0];
            }
        }
        return swrAll;
    }

    @Override
    public int getRfidStatus() {
        return 0;
    }
}
